
package com.hlkj.pay.app.merchant.ext.impl.wxpay.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitAccountBindContext;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitAccountContext;
import com.hlkj.pay.app.merchant.ext.impl.wxpay.constant.WxPayExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.wxpay.dto.WxAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.wxpay.dto.WxPayConfig;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.merchant.fund.MerchantFundAccountBindDO;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.AuthTypeEnum;
import com.ijpay.core.enums.RequestMethodEnum;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.RsaKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxDomainEnum;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/16 9:10
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class WxPayMerchantAccountHandler {

    private final OkHttpTemplate okHttpTemplate;

    private final WxPayCommonParamsHandle wxPayCommonParamsHandle;

    /**
     * @param channelProfitAccountContext
     */
    public void submitProfitAccount(ChannelProfitAccountContext channelProfitAccountContext) {
    }

    public void updateProfitAccount(ChannelProfitAccountContext channelProfitAccountContext) {
    }

    public void bindProfitAccount(ChannelProfitAccountBindContext channelMerchantAccessContext) {
        log.info("微信分账账号绑定 初始化请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));
        // 判断商户类型
        MerchantAppChannelDO merchantAppChannelDO = channelMerchantAccessContext.getMerchantAppChannelDO();
        if(merchantAppChannelDO.getType() != null && MerchantEnum.APP_CHANNEL_TYPE.MERCHANT_COMMON.getCode()  == merchantAppChannelDO.getType()){
            channelMerchantAccessContext.setRemark("微信普通商户不支持分账");
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        CommonResult<WxPayConfig> wxPayConfigCommonResult = wxPayCommonParamsHandle.wxPayConfig(channelMerchantAccessContext.getProviderChannelConfig(),
                channelMerchantAccessContext.isTest());
        if (!wxPayConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(wxPayConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        // 微信配置信息
        WxPayConfig wxPayConfig = wxPayConfigCommonResult.getData();
        // 分账信息
        MerchantFundAccountBindDO fundAccountBindDO = channelMerchantAccessContext.getMerchantFundAccountBindDto().getMerchantFundAccountBindDO();
        // 服务商
        WxAppChannelParams WxAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), WxAppChannelParams.class);
        // 获取公众号ID
        String pubAppid = wxPayCommonParamsHandle.getAppid(channelMerchantAccessContext.getProviderChannelConfig(), CommonEnum.COMMON_APP_TYPE.WECHAT_PUB);

        try {
            // 支付公钥 敏感信息加密
            PublicKey publicKey = RsaKit.loadPublicKey(PayKit.getPublicKeyByContent(PayKit.getCertFileContent(wxPayConfig.getPayPublicPath())));

            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put("sub_mchid", WxAppChannelParams.getSubMchId());
            reqBody.put("appid", pubAppid);
            reqBody.put("type", "PERSONAL_OPENID");
            reqBody.put("account", fundAccountBindDO.getAccountNo());
            // 分账接收方全称需要加密
            if(StrUtil.isNotEmpty(fundAccountBindDO.getName())){
                reqBody.put("name", wxPayCommonParamsHandle.rsaEncryptOAEP(fundAccountBindDO.getName(),publicKey));
            }
            reqBody.put("relation_type", "USER");
            log.info("微信分账账号绑定 请求参数:{}", JSONUtil.toJsonStr(reqBody));
            // 响应参数
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethodEnum.POST,
                    WxDomainEnum.CHINA.toString(),
                    "/v3/profitsharing/receivers/add",
                    wxPayConfig.getMchId(),
                    wxPayConfig.getSerialNo(),
                    wxPayConfig.getPayPublicId(),
                    wxPayConfig.getPrivateKeyPath(),
                    JSONUtil.toJsonStr(reqBody),
                    AuthTypeEnum.RSA.getCode()
            );
            log.info("微信分账账号绑定 返回参数:{}", JSONUtil.toJsonStr(response));
            JSONObject resp = JSONUtil.parseObj(response.getBody());
            if (response.getStatus() != WxPayExtConstant.OK ) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(resp.getStr("message"));
            }
        }
        catch (Exception e) {
            log.error("微信分账账号绑定,失败信息 message: {}", e);
            channelMerchantAccessContext.setRemark("微信分账账号绑定,失败信息" + e.getMessage());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void unBindProfitAccount(ChannelProfitAccountBindContext channelMerchantAccessContext) {
        log.info("微信分账账号解绑 初始化请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));
        // 判断商户类型
        MerchantAppChannelDO merchantAppChannelDO = channelMerchantAccessContext.getMerchantAppChannelDO();
        if(merchantAppChannelDO.getType() != null && MerchantEnum.APP_CHANNEL_TYPE.MERCHANT_COMMON.getCode()  == merchantAppChannelDO.getType()){
            channelMerchantAccessContext.setRemark("微信普通商户不支持分账");
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        CommonResult<WxPayConfig> wxPayConfigCommonResult = wxPayCommonParamsHandle.wxPayConfig(channelMerchantAccessContext.getProviderChannelConfig(),
                channelMerchantAccessContext.isTest());
        if (!wxPayConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(wxPayConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        // 微信配置信息
        WxPayConfig wxPayConfig = wxPayConfigCommonResult.getData();
        // 分账信息
        MerchantFundAccountBindDO fundAccountBindDO = channelMerchantAccessContext.getMerchantFundAccountBindDto().getMerchantFundAccountBindDO();
        // 服务商
        WxAppChannelParams WxAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), WxAppChannelParams.class);
        // 获取公众号ID
        String pubAppid = wxPayCommonParamsHandle.getAppid(channelMerchantAccessContext.getProviderChannelConfig(), CommonEnum.COMMON_APP_TYPE.WECHAT_PUB);
        try {
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put("sub_mchid", WxAppChannelParams.getSubMchId());
            reqBody.put("appid", pubAppid);
            reqBody.put("type", "PERSONAL_OPENID");
            reqBody.put("account", fundAccountBindDO.getAccountNo());
            log.info("微信分账账号解绑 请求参数:{}", JSONUtil.toJsonStr(reqBody));
            // 响应参数
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethodEnum.POST,
                    WxDomainEnum.CHINA.toString(),
                    "/v3/profitsharing/receivers/delete",
                    wxPayConfig.getMchId(),
                    wxPayConfig.getSerialNo(),
                    wxPayConfig.getPayPublicId(),
                    wxPayConfig.getPrivateKeyPath(),
                    JSONUtil.toJsonStr(reqBody),
                    AuthTypeEnum.RSA.getCode()
            );
            log.info("微信分账账号解绑 返回参数:{}", JSONUtil.toJsonStr(response));
            JSONObject resp = JSONUtil.parseObj(response.getBody());
            if (response.getStatus() != WxPayExtConstant.OK ) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(resp.getStr("message"));
            }
        }
        catch (Exception e) {
            log.error("微信分账账号解绑,失败信息 message: {}", e);
            channelMerchantAccessContext.setRemark("微信分账账号解绑,失败信息" + e.getMessage());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void queryAccountBindList(ChannelProfitAccountBindContext channelProfitAccountBindContext) {

    }


}
